package com.superatom.concurrent.basic.executor.exception;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

class ExceptionThread2 implements Runnable{

    public void run() {
        Thread t = Thread.currentThread();
        System.out.println("run() by" + t);
        System.out.println("eh = " + t.getUncaughtExceptionHandler());
        // 在ExceptionThread任务中模拟抛出一个运行时异常
        throw new RuntimeException();
    }
}

/**
 * 定义异常处理器
 */
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
    // 未能捕获到的线程异常，可以使用uncaughtException捕获
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("caught " + e);
    }
}

/**
 * 自定义线程工厂
 */
class HandlerThreadFactory implements ThreadFactory{

    public Thread newThread(Runnable r) {
        System.out.println(this + " creating new Thread");
        Thread t = new Thread();
        System.out.println("created " + t);
        // 配置异常处理器
        t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
        System.out.println("eh = " + t.getUncaughtExceptionHandler());
        return t;
    }
}

public class CaptureUncaughtException {
    public static void main(String[] args) {
        // 设置线程默认的未捕获异常处理
        // Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());

        // 使用自定义的线程工厂创建线程，为Thread对象配置异常处理器（可以为每个线程单独配置未捕获异常处理器）
        ExecutorService exec = Executors.newCachedThreadPool(
                new HandlerThreadFactory());

        // 执行此线程，会抛出异常，此时就会被正确捕捉并处理之
        exec.execute(new ExceptionThread2());
    }
}
